package net.aetherial.context.grounding.classifiers;

import java.util.*;

/**
 * An incomplete aggregate classifier that uses the AdaBoost algorithm for weighting predictions made by child classifiers.
 */

public class AdaBoostClassifier extends Classifier 
{
	private Map<Classifier, Double> classifiers;
	
	/**
	 * Sets the child classifiers.
	 * 
	 * @param cs	List of child classifiers.
	 */
	
	public void setClassifiers (List<Classifier> cs)
	{
		classifiers = new HashMap<Classifier, Double> ();
		
		double weight = 1.0 / cs.size ();
		
		Iterator<Classifier> iter = cs.iterator ();
		
		while (iter.hasNext ())
		{
			classifiers.put(iter.next(), new Double (weight));
		}
	}

	/**
	 * Trains the booster using training examples. Unimplemented.
	 * 
	 * @param trainingExamples		A set of training examples and labels.
	 */
	
	public void train (Map<String, String> trainingExamples)
	{

	}
	
	/**
	 * @see net.aetherial.context.grounding.classifiers.Classifier#classify(java.lang.String)
	 */
	
	public String classify (String contribution) 
	{
		HashMap<String, Double> votes = new HashMap<String, Double> ();
		
		Iterator<Classifier> iter = classifiers.keySet().iterator();

		while (iter.hasNext ())
		{
			Classifier c = iter.next ();
		
			String classification = c.classify (contribution);

			double tally = classifiers.get (c).doubleValue ();
			
			if (votes.containsKey (classification))
				tally += votes.get (classification).doubleValue ();
				
			votes.put (classification, new Double (tally));
		}

		String maxString = null;
		double maxScore = 0.0;
		
		Iterator<String> classifications = votes.keySet().iterator();
		
		while (classifications.hasNext ())
		{
			String classification = classifications.next ();
			double score = votes.get(classification).doubleValue ();
			
			if (score > maxScore)
			{
				maxString = classification;
				maxScore = score;
			}
			
		}

		return maxString;
	}
}
